package me.qi.kancha;

import me.qi.kancha.exception.MessageException;
import me.qi.kancha.exception.PreconditionException;
import me.qi.kancha.resp.FieldErrorException;
import me.qi.kancha.support.ErrorResult;
import me.qi.kancha.support.SimpleHashMap;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 全局异常处理器
 *
 * @author sun
 * @date 2019/6/3 17:49
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {

    @Override
    protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers,
                                                             HttpStatus status, WebRequest request) {
        //进入controller之前发生异常
        log.error("exception before controller on spring-mvc：" +  ex.getMessage());
        return new ResponseEntity(ex.getMessage(), headers, status);
    }

    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) //500
    public ErrorResult exceptionHandler(Exception e) {
        //业务方法中异常处理
        log.error("服务异常", e);
        return new ErrorResult(e.getMessage());
    }

    @ExceptionHandler(PreconditionException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST) //400
    public ErrorResult preconditionExceptionHandler(Exception e) {
        //业务方法中异常处理
        log.error("参数前置条件异常", e);
        return new ErrorResult(e.getMessage());
    }

    @ExceptionHandler(MessageException.class)
    @ResponseStatus(HttpStatus.OK) //200
    public Map messageExceptionHandler(Exception e) {
        //业务方法中异常处理
        log.error("异常消息", e);
        Map map = new HashMap();
        map.put("error_message", e.getMessage());
        return map;
    }

    @ExceptionHandler(FieldErrorException.class)
    @ResponseStatus(code = HttpStatus.BAD_REQUEST) //400
    public List<Map> exceptionHandler(FieldErrorException e) {
        List<Map> list = new ArrayList<>();
        e.getErrors().forEach(error -> list.add(new SimpleHashMap<>()
                .set("field", error.getField())
                .set("message", error.getDefaultMessage()))
        );
        log.info("字段校验失败" + list.toString());
        return list;
    }
}
